package com.qdd01.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qdd01.entity.Dto.CommentDto;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocket/comment/{videoId}")
@Component
@Slf4j
public class CommentWebSocket {

    // 修改 Map 的键类型为 Integer
    private static final ConcurrentHashMap<Integer, ConcurrentHashMap<String, Session>> VIDEO_SESSIONS = new ConcurrentHashMap<>();
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @OnOpen
    public void onOpen(Session session, @PathParam("videoId") Integer videoId) {
        if (videoId == null) {
            log.error("VideoId is null");
            try {
                session.close();
            } catch (IOException e) {
                log.error("Error closing session", e);
            }
            return;
        }

        // 确保 VIDEO_SESSIONS 中存在对应视频的 Map
        VIDEO_SESSIONS.computeIfAbsent(videoId, k -> new ConcurrentHashMap<>())
                .put(session.getId(), session);
            
        log.info("New WebSocket connection established - videoId: {}, sessionId: {}, total sessions for video: {}", 
            videoId, 
            session.getId(), 
            VIDEO_SESSIONS.get(videoId).size()
        );
    }

    @OnClose
    public void onClose(Session session, @PathParam("videoId") Integer videoId) {  // 改为 Integer
        ConcurrentHashMap<String, Session> videoSessions = VIDEO_SESSIONS.get(videoId);
        if (videoSessions != null) {
            videoSessions.remove(session.getId());
            if (videoSessions.isEmpty()) {
                VIDEO_SESSIONS.remove(videoId);
            }
        }
        log.info("WebSocket connection closed: videoId={}, sessionId={}", videoId, session.getId());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket error: sessionId=" + session.getId(), error);
    }

    // 修改参数类型为 Integer
    public static void broadcastComment(Integer videoId, CommentDto comment) {
        log.info("Attempting to broadcast comment for videoId: {}", videoId);
        
        ConcurrentHashMap<String, Session> videoSessions = VIDEO_SESSIONS.get(videoId);
        if (videoSessions != null) {
            log.info("Found {} active sessions for videoId: {}", videoSessions.size(), videoId);
            try {
                String message = objectMapper.writeValueAsString(comment);
                for (Session session : videoSessions.values()) {
                    if (session.isOpen()) {
                        session.getBasicRemote().sendText(message);
                        log.info("Successfully sent message to session: {}", session.getId());
                    } else {
                        log.warn("Session {} is not open, removing from active sessions", session.getId());
                        videoSessions.remove(session.getId());
                    }
                }
            } catch (IOException e) {
                log.error("Error broadcasting comment: {}", e.getMessage(), e);
            }
        } else {
            log.warn("No active sessions found for videoId: {}", videoId);
        }
    }
}